#include "packing_graphics.h"

namespace Packing
{
	static const GLfloat pgn_fill_color[] = {0.7f, 0.7f, 0.7f};
	static const GLfloat pgn_highlight_color[] = {0.0f, 0.9f, 0.0f};
	static const GLfloat pgn_large_room_color[] = {0.486f, 0.761f, 0.929f};
	static const GLfloat triangulation_edge_color[] = {0.85f, 0.0f, 0.0f};
	static const GLfloat voronoi_edge_color[] = {0.0f, 0.0f, 0.85f};
	static const GLfloat cat_edge_color[] = {0.85f, 0.0f, 0.85f};
	static const GLfloat c1 = 0.35f ;
	static const GLfloat c2 = 0.5f ;
	static const GLfloat c3 = 1.0f ;
	static GLfloat color_table[24][3] = 
	{
		{c3, c2, c2},{c2, c3, c2},{c2, c2, c3},{c2, c3, c3},{c3, c2, c3},{c3, c3, c2},
		{c1, c2, c2},{c2, c1, c2},{c2, c2, c1},{c2, c1, c1},{c1, c2, c1},{c1, c1, c2},
		{c1, c3, c3},{c3, c1, c3},{c3, c3, c1},{c3, c1, c1},{c1, c3, c1},{c1, c1, c3},
		{c1, c2, c3},{c1, c3, c2},{c2, c1, c3},{c2, c3, c1},{c3, c1, c2},{c3, c2, c1}
	} ;

	static int random_color_index_ = 0 ;
	static void gl_random_color() {
		glColor3f(
			color_table[random_color_index_][0], 
			color_table[random_color_index_][1], 
			color_table[random_color_index_][2]
		) ;
		random_color_index_ = (random_color_index_ + 1) % 12 ;
	}
	static void gl_random_color(int index) {
		random_color_index_ = index % 12 ;
		gl_random_color() ;
	}
	static void gl_randomize_colors() {
		random_color_index_ = 0 ;
	}
	Packing_graphics::Packing_graphics(Packer* _packer) : packer(_packer)//, show_domain_mesh_(true)
	{
		show_polygons = GL_TRUE;
		show_circles = GL_TRUE;
		show_triangulation = GL_FALSE;
		show_voronoi = GL_FALSE;
		show_cat = GL_FALSE;
		show_bd_box = GL_TRUE;
		highlight_no = -1;
		show_large_room = GL_FALSE;
	}
	Packing_graphics::~Packing_graphics()
	{

	}
	void Packing_graphics::draw()
	{
		glUseProgramObjectARB(0);
		
		//gl_randomize_colors();
		
		if (show_bd_box)
			packer->cbox->gl_draw();

		if (show_polygons)
			draw_polygons();
		if (show_circles)
		{
			for (unsigned int i = 0; i < packer->polygon_set.size(); i++)
			{
				packer->polygon_set[i]->gl_draw_circles(color_table[i%24]);
			}
		}
		if (show_triangulation)
			packer->pt->gl_draw_triangulation(triangulation_edge_color);
		if (show_voronoi)
		{
			//if (highlight_no >= 0)
				//packer->pt->gl_draw_intergroup_voronoi(voronoi_edge_color, highlight_no);
			packer->pt->gl_draw_intergroup_voronoi(voronoi_edge_color);
		}
		if (show_cat)
		{
			//if (highlight_no >= 0)
				//packer->pt->gl_draw_intergroup_cat(cat_edge_color, highlight_no);
			packer->pt->gl_draw_intergroup_cat(cat_edge_color);
		}
	}
	void Packing_graphics::redraw()
	{
		for (unsigned int i = 0; i < packer->polygon_set.size(); i++)
		{
			if (show_large_room)
			{
				if (packer->polygon_set[i]->large_neighbor_room())
				{
					glColor3fv(pgn_large_room_color);
					packer->polygon_set[i]->redraw(pgn_large_room_color);
				}
				else
				{
					glColor3fv(pgn_fill_color);
					packer->polygon_set[i]->redraw(pgn_fill_color);
				}
			}
			else
			{
				if (packer->polygon_set[i]->get_scale_factor() < 1.0)
				{
					glColor3fv(pgn_highlight_color);
					packer->polygon_set[i]->redraw(pgn_highlight_color);
				}
				else
				{
					glColor3fv(pgn_fill_color);
					packer->polygon_set[i]->redraw(pgn_fill_color);
				}
			}
		}
	}

	void Packing_graphics::draw_polygons()
	{
		//std::for_each(packer->polygon_set.begin(), packer->polygon_set.end(), std::bind2nd(std::mem_fun(&Packing_polygon::gl_draw), pgn_fill_color));
		for (unsigned int i = 0; i < packer->polygon_set.size(); i++)
		{
			if (show_large_room)
			{
				if (packer->polygon_set[i]->large_neighbor_room())
				{
					glColor3fv(pgn_large_room_color);
					packer->polygon_set[i]->gl_draw(pgn_large_room_color);
				}
				else
				{
					glColor3fv(pgn_fill_color);
					packer->polygon_set[i]->gl_draw(pgn_fill_color);
				}
			}
			else
			{
				if (packer->polygon_set[i]->get_scale_factor() < 1.0)
				{
					glColor3fv(pgn_highlight_color);
					packer->polygon_set[i]->gl_draw(pgn_highlight_color);
				}
				else
				{
					glColor3fv(pgn_fill_color);
					packer->polygon_set[i]->gl_draw(pgn_fill_color);
				}
			}
		}
	}
}
